package com.sprouting.ops.service;


import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.DES;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sprouting.ops.dao.DromaraFileStorageDao;
import com.sprouting.ops.dao.OpsUserDao;
import com.sprouting.ops.dao.OpsUserRoleDao;
import com.sprouting.ops.exception.ServiceException;
import com.sprouting.ops.interfaces.CacheKey;
import com.sprouting.ops.interfaces.ConstantBase;
import com.sprouting.ops.model.DromaraFileStorage;
import com.sprouting.ops.model.OpsUser;
import com.sprouting.ops.model.OpsUserRole;
import com.sprouting.ops.model.properties.LoginProperties;
import com.sprouting.ops.model.qo.UserQo;
import com.sprouting.ops.model.vo.UserCompositeVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * (User)表服务实现类
 *
 * @author longx
 * @since 2023-03-19 22:44:35
 */
@Service
@Slf4j
public class OpsUserService extends ServiceImpl<OpsUserDao, OpsUser> {

    @Resource
    private OpsUserDao opsUserDao;
    @Resource
    private LoginProperties loginProperties;
    @Resource
    private DromaraFileStorageDao dromaraFileStorageDao;
    @Autowired
    private OpsUserRoleDao opsUserRoleDao;


    /**
     * 根据用户名查询
     * @param userName 用户名
     * @return 用户
     */
    public OpsUser getByUserLoginName(String userName) {
        return opsUserDao.getByUserLoginName(userName);
    }

    /**
     * 解密信息- 解密前端加密数据
     * @param cipherText 密文
     * @return 解密后的数据
     */
    public String decrypt(String cipherText){
        cipherText = cipherText.trim();

        try {
            DES des = SecureUtil.des(loginProperties.getKey().getBytes(ConstantBase.Encoded.UTF));
            return des.decryptStr(cipherText);
        } catch (Exception e) {
            log.error("[解密] 对密文解密错误，密文：{}", cipherText);
            throw new ServiceException("非法参数，刷新后重试");
        }
    }

    /**
     * 根据部门ID查询一条绑定该ID的用户信息
     * @param deptId 部门ID
     * @return
     */
    public OpsUser getByDeptIdTop1(String deptId) {
        return opsUserDao.getByDeptIdTop1(deptId);
    }

    /**
     * 获取部门的人员
     * @param deptId 部门ID
     * @return
     */
    public List<OpsUser> getDeptUser(String deptId) {
        return opsUserDao.getDeptUser(deptId);
    }

    /**
     * 更新在登录中的用户缓存
     * @param userId 用户id
     */
    public void upOnLinedCache(String userId){
        // 检查用户是否在登录中，登录中则更新缓存
        SaSession session = StpUtil.getSessionByLoginId(userId, false);
        if (session != null){
            // 还要再次获取，刚进行了更新。上面的数据都不全或错误
            OpsUser dbUser = opsUserDao.selectById(userId);
            session.set(CacheKey.SaTokenSession.SESSION_KEY_USER, dbUser);
        }
    }

    /**
     * 根据登录用户名查询用户，并过滤指定ID
     * @param id 要过滤的ID
     * @param loginName 用户名，有且唯一
     * @return
     */
    public OpsUser getByUserNameFilterId(String id, String loginName) {
        return opsUserDao.getByUserNameFilterId(id, loginName);
    }

    /**
     * 保存用户
     * @param user 用户
     * @param unifiedFileInfo 头像
     * @param userRoleList 用户和角色
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveUser(OpsUser user, DromaraFileStorage unifiedFileInfo, List<OpsUserRole> userRoleList) {
        opsUserDao.insert(user);
        if (unifiedFileInfo != null){
            dromaraFileStorageDao.updateById(unifiedFileInfo);
        }

        if (CollUtil.isNotEmpty(userRoleList)){
            opsUserRoleDao.insertBatchSomeColumn(userRoleList);
        }
    }

    /**
     * 更新用户
     * @param user 用户
     * @param unifiedFileInfoArray 头像
     * @param userRoleList 用户和角色
     */
    @Transactional(rollbackFor = Exception.class)
    public void updUser(OpsUser user, DromaraFileStorage[] unifiedFileInfoArray, List<OpsUserRole> userRoleList) {
        opsUserDao.updateById(user);

        if (unifiedFileInfoArray[0] != null){
            // 新的
            dromaraFileStorageDao.updateById(unifiedFileInfoArray[0]);
        }
        if (unifiedFileInfoArray[1] != null){
            // 旧的文件
            dromaraFileStorageDao.updateById(unifiedFileInfoArray[1]);
        }

        // 角色删除
        LambdaQueryWrapper<OpsUserRole> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.eq(OpsUserRole::getUserId, user.getId());
        opsUserRoleDao.delete(roleWrapper);
        if (CollUtil.isNotEmpty(userRoleList)){
            opsUserRoleDao.insertBatchSomeColumn(userRoleList);
        }
    }

    /**
     * 删除用户
     * @param user 要删除的用户
     * @param unifiedFileInfo 用户头像
     */
    @Transactional(rollbackFor = Exception.class)
    public void delUser(OpsUser user, DromaraFileStorage unifiedFileInfo) {
        opsUserDao.deleteById(user);

        if (unifiedFileInfo != null){
            dromaraFileStorageDao.updateById(unifiedFileInfo);
        }

        // 解绑角色
        LambdaQueryWrapper<OpsUserRole> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.eq(OpsUserRole::getUserId, user.getId());
        opsUserRoleDao.delete(roleWrapper);
    }

    /**
     * 分页查询用户
     * @param page 分页参数
     * @param query 查询参数
     * @return
     */
    public Page<UserCompositeVo> getUserPage(Page page, UserQo query) {
        return opsUserDao.getUserPage(page, query);
    }
}

